package com.srmt.document.feishu.internal.table;

import com.lark.oapi.service.docx.v1.model.Block;
import com.srmt.document.exception.TableException;
import com.srmt.document.feishu.internal.table.impl.BitableStrategy;
import com.srmt.document.feishu.internal.table.impl.NormalTableStrategy;
import com.srmt.document.feishu.internal.table.impl.SheetStrategy;
import com.srmt.document.feishu.internal.table.model.TableType;
import com.srmt.feishu.client.FeishuClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;

/**
 * 表格操作策略工厂
 * 
 * 根据表格类型（blockType）返回相应的策略实现。
 * 使用单例模式管理策略实例，避免重复创建。
 * 
 * @author srmt
 * @since 3.0.0
 */
public class TableStrategyFactory {
    
    private static final Logger logger = LoggerFactory.getLogger(TableStrategyFactory.class);
    
    // 策略实例缓存
    private final Map<TableType, TableOperationStrategy> strategyCache;
    private final FeishuClient client;
    
    /**
     * 构造策略工厂
     * 
     * @param client 飞书客户端
     */
    public TableStrategyFactory(FeishuClient client) {
        if (client == null) {
            throw new IllegalArgumentException("客户端不能为null");
        }
        this.client = client;
        this.strategyCache = new HashMap<>();
        
        // 初始化策略
        initializeStrategies();
    }
    
    /**
     * 初始化所有策略实例
     */
    private void initializeStrategies() {
        // 注册普通表格策略 (blockType = 31)
        registerStrategy(new NormalTableStrategy(client));
        
        // 注册电子表格策略 (blockType = 30)
        registerStrategy(new SheetStrategy(client));
        
        // 注册多维表格策略 (blockType = 18)
        registerStrategy(new BitableStrategy(client));
        
        logger.info("已初始化 {} table strategies", strategyCache.size());
    }
    
    /**
     * 注册策略
     * 
     * @param strategy 策略实例
     */
    private void registerStrategy(TableOperationStrategy strategy) {
        if (strategy != null) {
            strategyCache.put(strategy.getTableType(), strategy);
            logger.debug("为{}注册策略: {}", 
                        strategy.getTableType(), 
                        strategy.getClass().getSimpleName());
        }
    }
    
    /**
     * 根据表格类型获取策略
     * 
     * @param tableType 表格类型
     * @return 对应的策略实例
     * @throws TableException 如果找不到对应的策略
     */
    public TableOperationStrategy getStrategy(TableType tableType) throws TableException {
        if (tableType == null) {
            throw new TableException("表格类型不能为null");
        }
        
        TableOperationStrategy strategy = strategyCache.get(tableType);
        if (strategy == null) {
            throw new TableException("No strategy found for table type: " + tableType);
        }
        
        logger.debug("Retrieved strategy for {}: {}", 
                    tableType, 
                    strategy.getClass().getSimpleName());
        
        return strategy;
    }
    
    /**
     * 根据blockType获取策略
     * 
     * @param blockType block类型编号
     * @return 对应的策略实例
     * @throws TableException 如果找不到对应的策略
     */
    public TableOperationStrategy getStrategyByBlockType(int blockType) throws TableException {
        TableType tableType = TableType.fromBlockType(blockType);
        
        if (tableType == TableType.UNKNOWN) {
            throw new TableException("Unknown block type: " + blockType);
        }
        
        return getStrategy(tableType);
    }
    
    /**
     * 根据Block获取策略
     * 
     * @param tableBlock 表格Block
     * @return 对应的策略实例
     * @throws TableException 如果找不到对应的策略
     */
    public TableOperationStrategy getStrategy(Block tableBlock) throws TableException {
        if (tableBlock == null) {
            throw new TableException("表格 block 不能为null");
        }
        
        if (tableBlock.getBlockType() == null) {
            throw new TableException("块类型未设置");
        }
        
        return getStrategyByBlockType(tableBlock.getBlockType());
    }
    
    /**
     * 判断是否支持指定的表格类型
     * 
     * @param tableType 表格类型
     * @return 是否支持
     */
    public boolean supportsTableType(TableType tableType) {
        return tableType != null && strategyCache.containsKey(tableType);
    }
    
    /**
     * 判断是否支持指定的blockType
     * 
     * @param blockType block类型编号
     * @return 是否支持
     */
    public boolean supportsBlockType(int blockType) {
        TableType tableType = TableType.fromBlockType(blockType);
        return tableType != TableType.UNKNOWN && supportsTableType(tableType);
    }
    
    // ========== 新增的细粒度接口获取方法 ==========
    
    /**
     * 获取表格读取策略
     * 
     * @param tableBlock 表格Block
     * @return 读取策略实例
     * @throws TableException 如果找不到对应的策略
     */
    public TableReadStrategy getReadStrategy(Block tableBlock) throws TableException {
        TableOperationStrategy strategy = getStrategy(tableBlock);
        if (strategy instanceof TableReadStrategy) {
            return (TableReadStrategy) strategy;
        }
        throw new TableException("Strategy does not support read operations: " + 
                                strategy.getClass().getSimpleName());
    }
    
    /**
     * 获取表格写入策略
     * 
     * @param tableBlock 表格Block
     * @return 写入策略实例
     * @throws TableException 如果找不到对应的策略
     */
    public TableWriteStrategy getWriteStrategy(Block tableBlock) throws TableException {
        TableOperationStrategy strategy = getStrategy(tableBlock);
        if (strategy instanceof TableWriteStrategy) {
            return (TableWriteStrategy) strategy;
        }
        throw new TableException("Strategy does not support write operations: " + 
                                strategy.getClass().getSimpleName());
    }
    
    /**
     * 获取表格结构操作策略
     * 
     * @param tableBlock 表格Block
     * @return 结构操作策略实例
     * @throws TableException 如果找不到对应的策略
     */
    public TableStructureStrategy getStructureStrategy(Block tableBlock) throws TableException {
        TableOperationStrategy strategy = getStrategy(tableBlock);
        if (strategy instanceof TableStructureStrategy) {
            return (TableStructureStrategy) strategy;
        }
        throw new TableException("Strategy does not support structure operations: " + 
                                strategy.getClass().getSimpleName());
    }
    
    /**
     * 获取所有支持的表格类型
     * 
     * @return 支持的表格类型集合
     */
    public TableType[] getSupportedTableTypes() {
        return strategyCache.keySet().toArray(new TableType[0]);
    }
    
    /**
     * 创建默认的策略工厂
     * 
     * @param client 飞书客户端
     * @return 策略工厂实例
     */
    public static TableStrategyFactory create(FeishuClient client) {
        return new TableStrategyFactory(client);
    }
    
    /**
     * 获取策略信息（用于调试）
     * 
     * @return 策略信息字符串
     */
    public String getStrategyInfo() {
        StringBuilder info = new StringBuilder();
        info.append("Table Strategy Factory Information:\n");
        info.append("Registered strategies: ").append(strategyCache.size()).append("\n");
        
        for (Map.Entry<TableType, TableOperationStrategy> entry : strategyCache.entrySet()) {
            TableType type = entry.getKey();
            TableOperationStrategy strategy = entry.getValue();
            info.append(String.format("  - %s (blockType=%d): %s\n", 
                                    type.getTypeName(), 
                                    type.getBlockType(), 
                                    strategy.getClass().getSimpleName()));
        }
        
        return info.toString();
    }
}